package org.springblade.modules.platform.websocket;


import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;

@Component
@Slf4j

public class WebSocketServer implements Runnable{
	@Autowired
	WebSocketPullService webSocketPullService;


	public void  start (Integer port) throws InterruptedException{
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		ServerBootstrap serverBootstrap = new ServerBootstrap();
		serverBootstrap.group(bossGroup, workerGroup)
			.channel(NioServerSocketChannel.class)
			.childHandler(new ChannelInitializer<SocketChannel>() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {
					ChannelPipeline pipeline = ch.pipeline();
					pipeline.addLast(new HttpServerCodec()); // HTTP 协议解析，用于握手阶段
					pipeline.addLast(new HttpObjectAggregator(65536)); // HTTP 协议解析，用于握手阶段
				/*	pipeline.addFirst("ssl", new SslHandler(getSslEngine()));*/
					pipeline.addLast(new WebSocketServerCompressionHandler()); // WebSocket 数据压缩扩展
					pipeline.addLast(new WebSocketServerProtocolHandler("/", null, true)); // WebSocket 握手、控制帧处理
					pipeline.addLast(new MyWebSocketHandler(webSocketPullService));
				}
			});
		ChannelFuture channelFuture1 = serverBootstrap.bind(port).syncUninterruptibly();//绑定端口，开启监听,同步等待
		if (channelFuture1 != null && channelFuture1.isSuccess()) {
			log.info("[WebSocket] server start success, port = {}", port);
		} else {
			log.error("WebSocket server start failed!!");
			channelFuture1.cause().printStackTrace();
		}

	}
	private SSLEngine getSslEngine() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
		String password = "12345678";
		// 以下为要支持wss所需处理
		KeyStore ks = KeyStore.getInstance("JKS");
		String keyFile = WebSocketServer.class.getResource("/jxzy-cert.jks").getPath();
		InputStream ksInputStream = new FileInputStream(keyFile);
		ks.load(ksInputStream, password.toCharArray());
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		kmf.init(ks, password.toCharArray());
		SSLContext sslContext = SSLContext.getInstance("TLS");
		sslContext.init(kmf.getKeyManagers(), null, null);
		SSLEngine sslEngine = sslContext.createSSLEngine();
		sslEngine.setUseClientMode(false);
		sslEngine.setNeedClientAuth(false);
		return sslEngine;
	}

	@Override
	public void run() {
		try {
			start(8808);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
	}
}
